package com.gugu.procedure.service;

import com.gugu.procedure.bean.Account;
import com.gugu.procedure.bean.MenuRoleRel;
import com.gugu.procedure.common.Constant;
import com.gugu.procedure.common.JwtOperator;
import com.gugu.procedure.common.MessageResult;
import com.gugu.procedure.dao.AccountDao;
import com.gugu.procedure.param.AccountUpdateParam;
import com.gugu.procedure.param.PasswordUpdateParam;
import com.gugu.procedure.util.DateUtil;
import com.gugu.procedure.util.SHAUtil;
import com.gugu.procedure.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.Predicate;
import java.util.*;

@Service
@Slf4j
public class AccountService {

    @Autowired
    private AccountDao accountDao;
    @Autowired
    private JwtOperator jwtOperator;
    @Autowired
    private MenuRoleRelService menuRoleRelService;

    /**
     * 登录
     *
     * @param account
     * @param password
     * @return
     */
    public MessageResult login(String account, String password) {
        Account bean = accountDao.findTopByAccount(account);
        if (bean == null) {
            return MessageResult.error("账号不存在");
        }
        String salt = bean.getSalt();
        password = SHAUtil.getSHA256Str(salt + password);
        if (!password.equals(bean.getPassword())) {
            return MessageResult.error("密码不正确");
        }
        Map<String, Object> map = new HashMap<>();
        map.put(Constant.ACCOUNT, bean.getAccount());
        map.put(Constant.ROLE, bean.getRole());
        map.put(Constant.NAME, bean.getName());
        map.put(Constant.MOBILE, bean.getMobile());
        map.put(Constant.TIME, System.currentTimeMillis());
        String token = jwtOperator.generateToken(map);
        Map<String, String> result = new HashMap<>();
        result.put("token", token);
        result.put("role", bean.getRole());
        result.put("name", bean.getName());
        MenuRoleRel menuRoleRel = menuRoleRelService.findByRole(bean.getRole());
        if (menuRoleRel != null) {
            result.put("menus", menuRoleRel.getMenus());
        } else {
            result.put("menus", "");
        }

        return MessageResult.getSuccessInstance(result);
    }


    public MessageResult page(String account, String role, String searchValue, int pageNo, int pageSize) {
        Specification<Account> spec = (Specification<Account>) (root, query, cb) -> {
            List<Predicate> list = new ArrayList<>();
            if (StringUtils.hasText(account)) {
                list.add(cb.equal(root.get("account").as(String.class), account));
            }
            if (StringUtils.hasText(role)) {
                list.add(cb.equal(root.get("role").as(String.class), role));
            }
            if (StringUtils.hasText(searchValue)) {
                Predicate pre = cb.equal(root.get("mobile").as(String.class), searchValue);
                pre = cb.or(pre, (cb.equal(root.get("name").as(String.class), searchValue)));
                list.add(pre);
            }
            list.add(cb.equal(root.get("isDel").as(String.class), Constant.IS_DEL_NO));
            Predicate[] pre = new Predicate[list.size()];
            query.where(list.toArray(pre));
            return query.getRestriction();
        };
        PageRequest pr = PageRequest.of(pageNo - 1, pageSize, Sort.Direction.DESC, "createTime");
        Page<Account> recordsPage = accountDao.findAll(spec, pr);
        MessageResult mr = MessageResult.success();
        mr.setTotal(recordsPage.getTotalElements());
        mr.setTotalElement(recordsPage.getContent());
        return mr;
    }

    public MessageResult update(AccountUpdateParam accountUpdateParam) {
        Account account = accountDao.findById(accountUpdateParam.getId()).get();
        if (Objects.isNull(account)) {
            return MessageResult.error("账号不存在");
        }
        // 如果账号不一样 看下新的账号是否数据库已存在
        if (StringUtil.notEquals(accountUpdateParam.getAccount(), account.getAccount())) {
            Account bean = accountDao.findTopByAccount(accountUpdateParam.getAccount());
            if (Objects.nonNull(bean)) {
                return MessageResult.error("账号已存在");
            }
        }
        BeanUtils.copyProperties(accountUpdateParam, account, "password");
        accountDao.save(account);
        return MessageResult.success();
    }

    public MessageResult deleteAccount(String account) {
        Account bean = accountDao.findTopByAccount(account);
        if (Objects.isNull(bean)) {
            return MessageResult.error("账号不存在");
        }
        bean.setIsDel(Constant.IS_DEL_YES);
        bean.setDeleteTime(DateUtil.getFormatedDateTime());
        accountDao.save(bean);
        return MessageResult.success();
    }

    public MessageResult add(AccountUpdateParam accountUpdateParam) {
        // 账号唯一校验
        Account account = accountDao.findTopByAccount(accountUpdateParam.getAccount());
        if (Objects.nonNull(account)) {
            return MessageResult.error("账号已存在");
        }
        account = new Account();
        BeanUtils.copyProperties(accountUpdateParam, account);
        String salt = StringUtil.getSalt();
        account.setSalt(salt);
        account.setIsDel(Constant.IS_DEL_NO);
        account.setCreateTime(DateUtil.getFormatedDateTime());
        String password = SHAUtil.getSHA256Str(salt + account.getPassword());
        account.setPassword(password);
        accountDao.save(account);
        return MessageResult.success();
    }


    public MessageResult updatePassword(PasswordUpdateParam passwordUpdateParam) {
        Account account = accountDao.findTopByAccount(passwordUpdateParam.getAccount());
        if (Objects.isNull(account)) {
            return MessageResult.error("账号不存在");
        }
        String pass = SHAUtil.getSHA256Str(account.getSalt() + passwordUpdateParam.getPassword());
        if (!pass.equals(account.getPassword())) {
            return MessageResult.error("原密码不正确");
        }
        String salt = StringUtil.getSalt();
        account.setSalt(salt);
        String password = SHAUtil.getSHA256Str(salt + passwordUpdateParam.getPasswordNew());
        account.setPassword(password);
        accountDao.save(account);
        return MessageResult.success();
    }

    public MessageResult updatePassword(String account, String password) {
        Account bean = accountDao.findTopByAccount(account);
        String salt = StringUtil.getSalt();
        bean.setSalt(salt);
        password = SHAUtil.getSHA256Str(salt + password);
        bean.setPassword(password);
        accountDao.save(bean);
        return MessageResult.success();
    }
}
